package com.ls.hashTab;


import lombok.Data;

import java.util.Objects;

/**
 * 简单hash表
 */
public class HashTable {
    // 存放数据的hash表
    private MyLinkedList[] arr;
    private Integer size = 0;


    /**
     * hash表中添加值
     * 0不成功 1 成功
     */
    public int add(Cat cat){
        // 计算索引值
        int index = hash(cat.getId());
        // 判断数组对于索引的链表是否有长度
        if (arr[index] !=null && arr[index].size()>0){
            // 说明对应索引有值了
            // 遍历链表，看是否已经存在
            if (arr[index].isContain(cat)){
                // 添加失败
                return 0;
            }else {
                arr[index].add(cat);
                return 1;
            }

        }else {
            arr[index] = new MyLinkedList(cat);
            return 1;
        }
    }

    /**
     * 查找
     */
    public Cat getCatById(Integer id){
        int index = hash(id);
        if (this.arr[index] != null){
            return this.arr[index].findById(id);
        }
        return null;
    }


    /**
     * 遍历hashTab
     */
    public void list(){
        for (int i = 0; i < arr.length; i++) {
            System.out.print("第"+(i+1)+"条链表"+":");
            if (arr[i] != null){
                arr[i].list();
            }else {
                System.out.print("为空");
            }
            System.out.println();
        }
    }



    public int hash(Integer key){
        return key % size;
    }

    public HashTable(Integer size) {
        this.size = size;
        this.arr = new MyLinkedList[size];
    }


    @Data  // 链表
    static class MyLinkedList{
        private MyLinkedList next;
        private Cat cat;
        // 链表长度
        private Integer size;
        public MyLinkedList(Cat cat) {
            this.cat = cat;
        }

        public MyLinkedList() {
        }

        public int size(){
            size = 1;
            MyLinkedList current = this;
            while (current.next != null){
                size++;
                current = current.next;
            }
            return size;
        }

        // 添加元素
       public void add(Cat cat){
           MyLinkedList current = this;
           while (current.next != null){
               current = current.next;
           }
           MyLinkedList myLinkedList = new MyLinkedList();
           myLinkedList.setCat(cat);
           current.setNext(myLinkedList);
       }

       public Cat findById(Integer id){
           MyLinkedList current = this;
           while (current != null){
               if (current.getCat().getId().equals(id)){
                   return current.getCat();
               }
               current = current.getNext();
           }
           return null;
       }



        // 遍历
        public void list(){
            MyLinkedList current = this;
            while (current.next != null){
                System.out.print(current.cat+"--->");
                current = current.next;
            }
            System.out.print(current.cat+"--->");
        }

        public boolean isContain(Cat cat){
            MyLinkedList current = this;
            while (current != null){
                if (current.getCat().equals(cat)){
                    return true;
                }
                current = current.getNext();
            }
            return false;
        }
    }

    @Data // 猫猫实体类
    static
    class Cat{
        Integer id;
        String name;


        public Cat(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Cat{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Cat cat = (Cat) o;
            return Objects.equals(id, cat.id) &&
                    Objects.equals(name, cat.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, name);
        }
    }


    public static void main(String[] args) {
//        MyLinkedList myLinkedList = new MyLinkedList(new Cat(1,"tom"));
//        myLinkedList.add(new Cat(2,"hellKitty"));
//        System.out.println(myLinkedList.size());
//        System.out.println(myLinkedList.isContain(new Cat(1,"tom")));

        // 测试哈希表
        HashTable hashTable = new HashTable(10);
        hashTable.add(new Cat(9,"tom"));
        hashTable.add(new Cat(99,"tom"));
        hashTable.add(new Cat(999,"tom"));
        hashTable.list();
        System.out.println(hashTable.getCatById(999));
    }
}
